package com.ankicoo.auth.config;

import com.ankicoo.auth.filter.LoginFilter;
import com.ankicoo.auth.relam.CustomerRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tk.mybatis.spring.annotation.MapperScan;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;


/**
 * Description: 配置
 *
 * @author : QCYANG
 * @date : 2021/1/11 14:46
 */
//@Configuration
//@EnableConfigurationProperties
//@MapperScan(basePackages = "com.ankicoo.auth.mapper")
public class AuthConfiguration {
    @Autowired
    private AuthenticationProperties authenticationProperties;
    @Autowired
    private ShiroFilterConfiguration shiroFilterConfiguration;

    @Bean
    public SessionManager sessionManager() {
        return new DefaultWebSessionManager();
    }

    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(CustomerRealm authUserRealm, SessionManager sessionManager) {
        DefaultWebSecurityManager defaultWebSecurityManager =new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(authUserRealm);
        defaultWebSecurityManager.setSessionManager(sessionManager);
        SecurityUtils.setSecurityManager(defaultWebSecurityManager);
        return defaultWebSecurityManager;
    }

    @Bean
    public CustomerRealm customizeRealm() {
        CustomerRealm customizeRealm = new CustomerRealm();
        customizeRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return customizeRealm;
    }

    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName(authenticationProperties.getHashAlgorithmName());
        credentialsMatcher.setHashIterations(authenticationProperties.getIterations());
        return credentialsMatcher;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(defaultWebSecurityManager);
        ShiroFilterConfiguration.ShiroUrlDefinition shiroUrlDefinition = shiroFilterConfiguration.getShiroUrlDefinition();

        shiroFilter.setLoginUrl(shiroUrlDefinition.loginUrl);
//        shiroFilter.setSuccessUrl("/");
        shiroFilter.setUnauthorizedUrl(shiroUrlDefinition.unauthorizedUrl);
        /*
         * 过滤器 {@Link DefaultFilter}
         *      anon:无需认证可以访问
         *      authc:需要认证才可访问
         *      user:rememberMe可访问
         *      perms:获得资源权限才可访问
         *      role:获得角色权限才可访问
         *      ......
         */
        Map<String, String> filterDefinitionMap = new LinkedHashMap<>();
        Map<String, List<String>> shiroFilterDefinitions = shiroFilterConfiguration.getShiroFilterDefinition();
        if (Optional.ofNullable(shiroFilterDefinitions).isPresent()) {
            shiroFilterDefinitions.forEach((definition, paths)->
                paths.forEach(path-> filterDefinitionMap.put(path, definition))
            );
        }
        filterDefinitionMap.put("/**", "authc");
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("authLogin", new LoginFilter());
        shiroFilter.setFilters(filterMap);
        shiroFilter.setFilterChainDefinitionMap(filterDefinitionMap);
        return shiroFilter;
    }
}
